import type { ComponentStyleIdType } from '../../types/interfaces'
import type { MenuItem, ToolbarProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ICON_IDS } from '../../lib/icons/types/constants'
import { ComponentStyleId } from '../../types/constants'
import { styles } from './styles'
import { DEFAULT_TOOLBAR_PROPS } from './types'

export class Toolbar extends UIComponent<ToolbarProps> {
  id: string = 'toolbar'
  readonly description: string = '工具栏组件'
  readonly styleId: string = ComponentStyleId[this.name]
  private activeMenu: string | null = null
  private readonly documentClickEventName: string

  get name(): ComponentStyleIdType {
    return 'Toolbar'
  }

  get className(): string {
    return `${this.props.id}-custom-toolbar-container`
  }

  constructor(props: ToolbarProps) {
    super({
      ...DEFAULT_TOOLBAR_PROPS,
      ...props,
    })

    this.documentClickEventName = `click.${this.props.id}-toolbar`

    // 注册样式
    this.registerStyles()
  }

  ELEMENT_SELECTORS = {
    menu: { selector: '.toolbar-menu', dynamic: false, unique: true },
    menuButton: { selector: '.toolbar-menu-button', dynamic: false, unique: true },
    submenuButton: { selector: '.toolbar-submenu-item', dynamic: false, unique: true },
  }

  render(): string {
    const { position } = this.props
    const positionStyle = position === 'left' ? 'flex-start' : 'flex-end'

    return `
      <div class="${this.className} custom-toolbar" style="display: flex; justify-content: ${positionStyle}; width: 100%;">
        <div class="toolbar">
            ${this.props.menus.map(menu => this.renderMenu(menu)).join('')}
        </div>
      </div>
    `
  }

  /**
   * 渲染单个菜单项
   */
  private renderMenu(menu: MenuItem): string {
    const hasChildren = menu.children && menu.children.length > 0
    const isActive = this.activeMenu === menu.id
    const disabledClass = menu.disabled ? 'disabled' : ''

    return `
      <div class="toolbar-menu ${isActive ? 'active' : ''} ${menu.className || ''}">
        <button 
          class="toolbar-menu-button  ${disabledClass} ${isActive ? 'active' : ''}"
          data-id="${menu.id}"
          ${menu.disabled ? 'disabled' : ''}
        >
          ${menu.icon ? `<span class="menu-icon">${menu.icon}</span>` : ''}
          <span class="menu-name">${menu.text}</span>
          ${hasChildren ? `<span class="toolbar-icon">${this.iconService.api.icon.asSvg(ICON_IDS.navigation.arrowsDown)}</span>` : ''}
        </button>
        ${hasChildren ? this.renderSubmenu(menu) : ''}
      </div>
    `
  }

  /**
   * 渲染子菜单
   */
  private renderSubmenu(menu: MenuItem): string {
    return `
      <div class="toolbar-submenu">
        ${menu.children!.map(child => this.renderSubmenuItem(child, menu.id)).join('')}
      </div>
    `
  }

  /**
   * 渲染子菜单项
   */
  private renderSubmenuItem(item: MenuItem, parentId: string): string {
    const disabledClass = item.disabled ? 'disabled' : ''
    const mutualExclusionId = item.mutualExclusionId || ''

    return `
      <div 
        class="toolbar-submenu-item ${disabledClass} ${item.className || ''}"
        data-id="${item.id}"
        data-parent-id="${parentId}"
        ${mutualExclusionId ? `data-mutual-exclusion-id="${mutualExclusionId}"` : ''}
        ${item.disabled ? 'disabled' : ''}
        ${item.title ? `title="${item.title.replace(/\n/g, '&#10;')}"` : ''}
      >
        ${item.icon ? `<span class="submenu-icon">${item.icon}</span>` : ''}
        <span class="submenu-name">${item.text}</span>
      </div>
    `
  }

  bindEvents(): void {
    // 1. 绑定一级菜单点击事件
    this.$element?.find('.toolbar-menu-button')?.on('click', (e) => {
      const target = $(e.currentTarget)

      if (target.hasClass('disabled'))
        return

      this.handleMenuClick(target)
    })

    // 2. 绑定二级菜单点击事件
    this.$element?.find('.toolbar-submenu-item')?.on('click', (e) => {
      const target = $(e.currentTarget)

      if (target.hasClass('disabled'))
        return

      this.handleSubMenuClick(target, e)
    })

    // 3. 点击外部关闭菜单
    $(document).on(this.documentClickEventName, (e) => {
      if (this.activeMenu !== null && !$(e.target).closest('.toolbar').length) {
        this.closeAllMenus()
      }
    })

    // 4. 鼠标移出二级菜单自动关闭
    this.$element?.on('mouseleave', '.toolbar-submenu', (e) => {
      // 延迟检查以确保不是移动到子菜单项
      setTimeout(() => {
        const $submenu = $(e.currentTarget)
        if (!$submenu.find(':hover').length) {
          this.closeAllMenus()
        }
      }, 100)
    })
  }

  /**
   * 处理菜单点击
   */
  private handleMenuClick(target: JQuery<HTMLElement>): void {
    const menuId = target.data('id')
    this.toggleMenu(menuId)
  }

  /**
   * 处理菜单点击
   */
  private handleSubMenuClick(target: JQuery<HTMLElement>, e: JQuery.ClickEvent): void {
    const menuId = target.data('id')
    const parentId = target.data('parent-id')
    const menu = this.findMenuById(menuId, parentId)

    if (!menu)
      return

    // 执行自定义点击处理
    if (menu?.onClick) {
      menu.onClick(menu, e)
    }
    else if (parentId) {
      // 子菜单默认行为
      this.closeAllMenus()
    }
  }

  /**
   * 根据 ID 查找菜单项
   */
  private findMenuById(id: string, parentId?: string): MenuItem | undefined {
    if (parentId) {
      const parent = this.props.menus.find(m => m.id === parentId)
      return parent?.children?.find(c => c.id === id)
    }
    return this.props.menus.find(m => m.id === id)
  }

  /**
   * 切换菜单状态
   */
  private toggleMenu(menuId: string): void {
    if (this.activeMenu === menuId) {
      this.closeAllMenus()
    }
    else {
      this.closeAllMenus()
      this.activeMenu = menuId

      this.getElement('menuButton')?.removeClass('active')
      this.getElement('menu')?.removeClass('active')

      const activeButton = this.getElement('menuButton')?.filter(`[data-id="${menuId}"]`)
      activeButton?.addClass('active')
      activeButton?.closest('.toolbar-menu').addClass('active')
    }
  }

  /**
   * 关闭所有菜单
   */
  private closeAllMenus(): void {
    this.activeMenu = null
    this.getElement('menuButton')?.removeClass('active')
    this.getElement('menu')?.removeClass('active')
  }

  getStyles(): string {
    return styles(this.className, this.props)
  }

  destroy(): void {
    super.destroy()
  }

  removeEventListeners(): void {
    // 1. 移除文档级点击事件
    $(document).off(this.documentClickEventName)

    // 2. 移除菜单按钮事件
    this.$element?.find('[data-id]').off('click')

    // 3. 移除可能存在的其他事件
    this.$element?.off()
  }

  cleanupReferences(): void {
    // 1. 移除 DOM 元素
    $(this.selector)?.remove()

    // 3. 重置活动菜单状态
    this.activeMenu = null
  }
}
